From 2bd0e7b9652a975f6dc89faf4eba904cf27f4d3b Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 21 Feb 2008 14:50:27 +0000 Subject: [PATCH] x86_emulate: Allow writeback-avoidance optimisation to be defeated by the caller. This is used in cases where the writeback may be to an MMIO region with side effects (the APIC EOI register is the main example of this). Also fix up build of the x86_emulate user-space test harness. Signed-off-by: Keir Fraser --- tools/tests/test_x86_emulator.c | 1 + xen/arch/x86/hvm/emulate.c | 1 + xen/arch/x86/mm.c | 1 + xen/arch/x86/mm/shadow/common.c | 1 + xen/arch/x86/x86_emulate.c | 4 +++- xen/include/asm-x86/x86_emulate.h | 27 +++++++++++++++------------ 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/tools/tests/test_x86_emulator.c b/tools/tests/test_x86_emulator.c index f261e7f4da..fe48921b59 100644 --- a/tools/tests/test_x86_emulator.c +++ b/tools/tests/test_x86_emulator.c @@ -118,6 +118,7 @@ int main(int argc, char **argv) #endif ctxt.regs = ®s; + ctxt.force_writeback = 0; ctxt.addr_size = 32; ctxt.sp_size = 32; diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c index 73649313ac..2bbdb505e9 100644 --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -722,6 +722,7 @@ void hvm_emulate_prepare( struct cpu_user_regs *regs) { hvmemul_ctxt->ctxt.regs = regs; + hvmemul_ctxt->ctxt.force_writeback = 1; hvmemul_ctxt->seg_reg_accessed = 0; hvmemul_ctxt->seg_reg_dirty = 0; hvmemul_get_seg_reg(x86_seg_cs, hvmemul_ctxt); diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 469842787e..e84b185598 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3671,6 +3671,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, goto bail; ptwr_ctxt.ctxt.regs = regs; + ptwr_ctxt.ctxt.force_writeback = 0; ptwr_ctxt.ctxt.addr_size = ptwr_ctxt.ctxt.sp_size = is_pv_32on64_domain(d) ? 32 : BITS_PER_LONG; ptwr_ctxt.cr2 = addr; diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index d30e7e721a..240d9100f0 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -385,6 +385,7 @@ struct x86_emulate_ops *shadow_init_emulation( unsigned long addr; sh_ctxt->ctxt.regs = regs; + sh_ctxt->ctxt.force_writeback = 0; if ( !is_hvm_vcpu(v) ) { diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index b240a0a48e..fb3280d505 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -24,6 +24,7 @@ #ifndef __XEN__ #include #include +#include #include #else #include @@ -1983,7 +1984,8 @@ x86_emulate( } break; case OP_MEM: - if ( !(d & Mov) && (dst.orig_val == dst.val) ) + if ( !(d & Mov) && (dst.orig_val == dst.val) && + !ctxt->force_writeback ) /* nothing to do */; else if ( lock_prefix ) rc = ops->cmpxchg( diff --git a/xen/include/asm-x86/x86_emulate.h b/xen/include/asm-x86/x86_emulate.h index 53d12f52be..d92df355d3 100644 --- a/xen/include/asm-x86/x86_emulate.h +++ b/xen/include/asm-x86/x86_emulate.h @@ -56,17 +56,17 @@ enum x86_segment { * segment descriptor. It happens to match the format of an AMD SVM VMCB. */ typedef union segment_attributes { - u16 bytes; + uint16_t bytes; struct { - u16 type:4; /* 0; Bit 40-43 */ - u16 s: 1; /* 4; Bit 44 */ - u16 dpl: 2; /* 5; Bit 45-46 */ - u16 p: 1; /* 7; Bit 47 */ - u16 avl: 1; /* 8; Bit 52 */ - u16 l: 1; /* 9; Bit 53 */ - u16 db: 1; /* 10; Bit 54 */ - u16 g: 1; /* 11; Bit 55 */ + uint16_t type:4; /* 0; Bit 40-43 */ + uint16_t s: 1; /* 4; Bit 44 */ + uint16_t dpl: 2; /* 5; Bit 45-46 */ + uint16_t p: 1; /* 7; Bit 47 */ + uint16_t avl: 1; /* 8; Bit 52 */ + uint16_t l: 1; /* 9; Bit 53 */ + uint16_t db: 1; /* 10; Bit 54 */ + uint16_t g: 1; /* 11; Bit 55 */ } fields; } __attribute__ ((packed)) segment_attributes_t; @@ -75,10 +75,10 @@ typedef union segment_attributes { * Again, this happens to match the format of an AMD SVM VMCB. */ struct segment_register { - u16 sel; + uint16_t sel; segment_attributes_t attr; - u32 limit; - u64 base; + uint32_t limit; + uint64_t base; } __attribute__ ((packed)); /* @@ -368,6 +368,9 @@ struct x86_emulate_ctxt /* Stack pointer width in bits (16, 32 or 64). */ unsigned int sp_size; + + /* Set this if writes may have side effects. */ + int force_writeback; }; /* -- 2.30.2